package menu

import (
	"context"
	"wh-1-backend/internal/dao"
	"wh-1-backend/internal/model"
	"wh-1-backend/internal/model/do"
	"wh-1-backend/internal/model/entity"
	"wh-1-backend/internal/service"
)

type sMenu struct{}

func New() *sMenu {
	return &sMenu{}
}

func init() {
	service.RegisterMenu(New())
}

func (m *sMenu) List(ctx context.Context, page int, pageSize int) (total int, res []*entity.AdminMenu, err error) {
	total, err = dao.AdminMenu.Ctx(ctx).Count()
	if err != nil {
		return
	}
	if total > 0 {
		err = dao.AdminMenu.Ctx(ctx).Page(page, pageSize).Scan(&res)
	}
	return
}

func (m *sMenu) Tree(ctx context.Context) ([]*model.MenuTreeItem, error) {
	var list []*model.MenuTreeItem
	err := dao.AdminMenu.Ctx(ctx).Scan(&list)
	if err != nil {
		return nil, err
	}
	return m.MakeTree(list), nil
}

func (m *sMenu) Store(ctx context.Context, input model.MenuCreateInput) error {
	_, err := dao.AdminMenu.Ctx(ctx).Data(input).Insert()
	return err
}

func (m *sMenu) Update(ctx context.Context, id uint, input do.AdminMenu) error {
	_, err := dao.AdminMenu.Ctx(ctx).Data(input).
		Where(dao.AdminMenu.Columns().Id, id).
		Update()
	return err
}

func (m *sMenu) Delete(ctx context.Context, id uint) error {
	_, err := dao.AdminMenu.Ctx(ctx).Delete(do.AdminMenu{Id: id})
	return err
}

func (m *sMenu) MakeTree(list []*model.MenuTreeItem) []*model.MenuTreeItem {
	m1 := make(map[uint]*model.MenuTreeItem)
	for _, v := range list {
		m1[v.Id] = v
	}
	tree := make([]*model.MenuTreeItem, 0)
	for _, v := range list {
		if m, ok := m1[v.Pid]; ok {
			m.Children = append(m.Children, v)
		} else {
			tree = append(tree, v)
		}
	}
	return tree
}

func (m *sMenu) GetListByRoleId(ctx context.Context, ids []uint) (res []*model.MenuTreeItem, err error) {
	var roleRelMenuList []*entity.AdminRoleRelMenu
	err = dao.AdminRoleRelMenu.Ctx(ctx).WhereIn(dao.AdminUserRelRole.Columns().RoleId, ids).Scan(&roleRelMenuList)
	if err != nil {
		return
	}
	var menuIds []uint
	for _, relMenu := range roleRelMenuList {
		menuIds = append(menuIds, relMenu.MenuId)
	}
	res, err = m.GetListById(ctx, menuIds)
	return
}

func (m *sMenu) GetListById(ctx context.Context, ids []uint) (res []*model.MenuTreeItem, err error) {
	err = dao.AdminMenu.Ctx(ctx).WhereIn(dao.AdminMenu.Columns().Id, ids).Scan(&res)
	return
}

func (m *sMenu) GetSimpleListById(ctx context.Context, ids []uint) (res []*model.MenuSimpleTreeItem, err error) {
	err = dao.AdminMenu.Ctx(ctx).
		WhereIn(dao.AdminMenu.Columns().Id, ids).
		Fields(dao.AdminMenu.Columns().Id).
		Fields(dao.AdminMenu.Columns().Title).
		Fields(dao.AdminMenu.Columns().Pid).
		Scan(&res)
	return
}
